#ifndef RANDOM
#define RANDOM

/* The random number generator used herein is not threadsafe. Thus, only a single 
constructor call should be done. I'm enforcing this here by use of a static bool 
to ensure the random number generator is seeded only once. Since the seed is a 
global variable, common across threads, I'm also using locking to ensure that 
multiple threads don't try to use these facilities at the same time.
*/

#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <limits.h>
#include "Locker.h"

#define srandom srand
#define random rand

class Random  {
private:
    static bool seeded;
    static Locker l;

public:
    Random() {
        l.Lock();
        if (! seeded) {
            //printf("Random: Constructor\n");

            // see http://www.eternallyconfuzzled.com/arts/jsw_art_rand.aspx
            time_t now = time ( 0 );
            unsigned char *p = (unsigned char *)&now;
            unsigned seed = 0;
            size_t i;
     
            for ( i = 0; i < sizeof now; i++ )
                seed = seed * ( UCHAR_MAX + 2U ) + p[i];

            srandom(seed); 
            seeded = true;
        }
        l.Unlock();
    }

	// Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) 
	// and the specified value (exclusive).
    int nextInt(int range) {
        int r;
        l.Lock();
        r = random() % range;
        l.Unlock();
        return r;
    }

    /* Return a random floating point value between 0 (inclusive) and 1 (exclusive).
    */
    float nextFloat() {
        float r;
        r =  nextInt(100)/100.0; // nextInt is protected with a lock
        return r;
    }
};

bool Random::seeded = false;
Locker Random::l;

#endif

